home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
EnigmA Amiga Run 1995 November
/
EnigmA AMIGA RUN 02 (1995)(G.R. Edizioni)(IT)[!][issue 1995-11][Skylink CD].iso
/
earcd
/
ear
/
mui23dev.lha
/
MUI
/
Developer
/
Modula
/
Demo
/
Class1.mod
< prev
next >
Wrap
Text File
|
1994-06-27
|
9KB
|
294 lines
MODULE Class1;
(*$ StackChk:=FALSE NilChk:=FALSE EntryClear:=FALSE
RangeChk:=FALSE
*)
(*
** Class1
** the M2 interpretation of the famous class written by Stefan Stuntz
** for MUI in C.
** This demonstration was performed by Christian 'Kochtopf' Scholz in
** order to show how the same is done in M2.
** (ofcourse inspired by class1.c ;-) )
**
** please note that there are some foldmarkers inside this file, which
** are used by GoldEd.
*)
(*{{{ "Imports" *)
IMPORT MD:MuiD;
IMPORT ML:MuiL;
IMPORT MM:MuiMacros;
IMPORT R;
IMPORT Arts;
FROM SYSTEM IMPORT ADDRESS, LONGSET, TAG, CAST, ADR;
FROM ExecL IMPORT Wait;
FROM MuiMacros IMPORT MakeHook, HookDef, NoteClose, set;
FROM MuiSupport IMPORT fail, DoMethod, DOMethod, APTR;
FROM IntuitionD IMPORT IClassPtr, ObjectPtr, DrawPens, DrawInfo, Msg, IClass;
FROM IntuitionL IMPORT FreeClass, MakeClass, NewObjectA;
FROM MuiClasses IMPORT mpAskMinMax, mpAskMinMaxPtr, mpDraw, mpDrawPtr,
MADFlagSet, MADFlags,
OBJ_rp, OBJ_dri, OBJ_mleft, OBJ_mtop, OBJ_mbottom, OBJ_mright,
mpSetUp, mMinMax, FillMinMaxInfo, MakeDispatcher;
FROM AmigaLib IMPORT DoSuperMethodA;
FROM GraphicsL IMPORT SetAPen, Move, Draw;
FROM GraphicsD IMPORT RastPortPtr;
FROM UtilityD IMPORT HookPtr, Hook, tagDone, tagEnd;
FROM Terminal IMPORT Format;
(*}}}*)
(*{{{ "the class" *)
(***************************************************************************)
(* Here is the beginning of our simple new class... *)
(***************************************************************************)
(*
** This is an example for the simplest possible MUI class. It's just some
** kind of custom image and supports only two methods:
** mAskMinMax and mDraw.
*)
(*
** This is the instance data for our custom class.
** Since it's a very simple class, it contains just a dummy entry.
*)
TYPE Data = RECORD
dummy : LONGINT;
END;
VAR MyData : Data;
(*{{{ "mAskMinMax" *)
(*
** AskMinMax method will be called before the window is opened
** and before layout takes place. We need to tell MUI the
** minimum, maximum and default size of our object.
*)
PROCEDURE mAskMinMax(cl : IClassPtr; obj : ObjectPtr; msg : mpAskMinMaxPtr) : ADDRESS;
VAR dummy : ADDRESS;
BEGIN
(*
** let our superclass first fill in what it thinks about sizes.
** this will e.g. add the size of frame and inner spacing.
*)
dummy:=DoSuperMethodA(cl,obj,msg);
(*
** now add the values specific to our object. note that we
** indeed need to *add* these values, not just set them!
*)
msg^.MinMaxInfo^.MinWidth := msg^.MinMaxInfo^.MinWidth +100;
msg^.MinMaxInfo^.DefWidth := msg^.MinMaxInfo^.DefWidth +120;
msg^.MinMaxInfo^.MaxWidth := msg^.MinMaxInfo^.MaxWidth +500;
msg^.MinMaxInfo^.MinHeight := msg^.MinMaxInfo^.MinHeight +40;
msg^.MinMaxInfo^.DefHeight := msg^.MinMaxInfo^.DefHeight +90;
msg^.MinMaxInfo^.MaxHeight := msg^.MinMaxInfo^.MaxHeight +300;
(*
** please note that there is a PROCEDURE defined in MUIClasses,
** which does the settings of the MinMaxInfo.
** just call
** FillMinMaxInfo(msg, 100, 120, 500, 40, 90, 300);
** in order to do the same as above in one line.
*)
RETURN NIL;
END mAskMinMax;
(*}}}*)
(*{{{ "mDraw" *)
(*
** Draw method is called whenever MUI feels we should render
** our object. This usually happens after layout is finished
** or when we need to refresh in a simplerefresh window.
** Note: You may only render within the rectangle
** OBJ_mleft(obj), OBJ_mtop(obj), OBJ_mwidth(obj), OBJ_mheight(obj).
*)
PROCEDURE mDraw(cl : IClassPtr; obj : ObjectPtr; msg : mpDrawPtr) : ADDRESS;
VAR
i : INTEGER;
dummy : ADDRESS;
mt, ml, mr, mb : INTEGER;
BEGIN
(*
** let our superclass draw itself first, area class would
** e.g. draw the frame and clear the whole region. What
** it does exactly depends on msg->flags.
*)
dummy:=DoSuperMethodA(cl,obj,msg);
(*
** if drawObject isn't in MADFlagSet, we shouldn't draw anything.
** MUI just wanted to update the frame or something like that.
*)
IF (drawObject IN msg^.flags) THEN
(*
** ok, everything ready to render...
*)
mt:=OBJ_mtop(obj);
ml:=OBJ_mleft(obj);
mr:=OBJ_mright(obj);
mb:=OBJ_mbottom(obj);
SetAPen(OBJ_rp(obj), OBJ_dri(obj)^.pens^[textPen]);
FOR i:=ml TO mr BY 5 DO
Move(OBJ_rp(obj), ml, mb);
Draw(OBJ_rp(obj), i, mt);
Move(OBJ_rp(obj), mr, mb);
Draw(OBJ_rp(obj), i, mt);
END;
END; (* if *)
RETURN NIL;
END mDraw;
(*}}}*)
(*{{{ "MyDispatcher" *)
(*
** Here comes the dispatcher for our custom class. We only need to
** care about mAskMinMax and mDraw in this simple case.
** Unknown/unused methods are passed to the superclass immediately.
*)
PROCEDURE MyDispatcher(cl : IClassPtr; obj : ADDRESS; msg : ADDRESS) : ADDRESS;
BEGIN
(* sorry, no CASE here, because the range is too big... *)
IF CAST(Msg, msg)^.methodID=MD.mmAskMinMax THEN
RETURN mAskMinMax(cl, obj, msg);
ELSIF CAST(Msg, msg)^.methodID=MD.mmDraw THEN
RETURN mDraw(cl, obj,msg);
ELSE
RETURN DoSuperMethodA(CAST(IClassPtr, cl), obj, msg);
END;
END MyDispatcher;
(*}}}*)
(*}}}*)
(***************************************************************************)
(* Thats all there is about it. Now lets see how things are used... *)
(***************************************************************************)
(*{{{ "VAR" *)
VAR app, window, MyObj, SuperClass : APTR;
myObj : APTR;
MyClass : IClassPtr;
signals : LONGSET;
running :=BOOLEAN{TRUE};
myHookPtr : HookPtr;
buffer, buffer2 : ARRAY[0..60] OF LONGINT;
NULL :=ADDRESS{NIL};
du : BOOLEAN;
(*}}}*)
(*{{{ "usage of the class" *)
BEGIN
(* Get a pointer to the superclass. MUI will lock this *)
(* and prevent it from being flushed during you hold *)
(* the pointer. When you're done, you have to call *)
(* moFreeClass() to release this lock. *)
SuperClass:=ML.moGetClass(ADR(MD.mcArea));
IF SuperClass=NIL THEN fail(NULL, "Superclass for the new class not found,"); END;
(* create the new class *)
MyClass:=MakeClass(NIL, NIL, SuperClass, SIZE(MyData), LONGSET{});
IF MyClass=NIL THEN
ML.moFreeClass(SuperClass);
fail(NULL, "Failed to create class!");
END;
(* set the dispatcher for the new class *)
MakeDispatcher(MyDispatcher, MyClass);
(* create a little GUI with our new class *)
MyObj := NewObjectA(MyClass, NIL, TAG(buffer,
MD.maFrame, MD.mvFrameText,
MD.maBackground, MD.miBACKGROUND,
tagDone));
window := MM.WindowObject(TAG(buffer,
MD.maWindowTitle, ADR("A test of our custom class"),
MM.WindowContents, MM.VGroup(TAG(buffer2,
MM.Child, MyObj,
tagEnd)),
tagEnd));
app := MM.ApplicationObject(TAG(buffer,
MD.maApplicationTitle, ADR("M2Class1"),
MD.maApplicationAuthor, ADR("Christian Scholz and Stefan Stuntz"),
MD.maApplicationVersion, ADR("$VER: M2Class1 1.0 (18.04.94)"),
MD.maApplicationCopyright, ADR("© KT SS"),
MD.maApplicationDescription, ADR("demonstrates how to write own classes in M2!"),
MD.maApplicationBase, ADR("M2CLASS1"),
MM.SubWindow, window,
tagEnd));
IF app=NIL THEN fail(app, "failed to create application!!"); END;
NoteClose(app, window, MD.mvApplicationReturnIDQuit); (* set up a notify on closing the window *)
(*
** Input loop...
*)
set(window,MD.maWindowOpen,1);
WHILE running DO
CASE DOMethod(app, TAG(buffer,
MD.mmApplicationInput, ADR(signals))) OF
| MD.mvApplicationReturnIDQuit :
running:=FALSE;
ELSE
END;
IF running AND (signals <> LONGSET{} ) THEN signals:=Wait(signals);
END;
END; (* While *)
set(window,MD.maWindowOpen,0);
(*
** Shut down...
*)
ML.mDisposeObject(app); (* free our application resources *)
du:=FreeClass(MyClass); (* free our own class *)
ML.moFreeClass(SuperClass); (* free our SuperClass *)
fail(NULL,""); (* and the end..... *)
(*}}}*)
END Class1.